home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 9
/
FM Towns Free Software Collection 9.iso
/
t_os
/
tool
/
otohime
/
src
/
lib
/
vchan.asm
< prev
next >
Wrap
Assembly Source File
|
1994-11-16
|
12KB
|
618 lines
; VOICE CHANGER
;
; call from F-BASIC386 or High C
; callm address,varptr(source),varptr(new),varptr(param),varptr(work)
; void VCHAN(*sourcesnd,*newsnd,*param,*work)
;
;
; 1990 3 Hiroshi TODA
;
; 1993 12 High C 用に改造
;
; param: cycle , mode*10000H
; work area = 256Byte
;
;
.386p
param struc
dd ?
dd ?
source dd ? ; source snd.data address
new dd ? ; new snd.data address
paradd dd ? ; param. address
wadd dd ? ; work address
param ends
work struc
;data area
cycle dd ? ; cycle
mode dd ? ; rate
;work area
point dd ? ; ov.sampling point (decimal)
dd ? ; ov.sampling point (integer)
rate dd ? ; add (decimal)
dd ? ; add (integer)
rend dd ? ; read end
rated dd ? ; add rate
ratea dd ? ; add buf.
pbuf dd ? ; point buf. (decimal)
dd ? ; point buf. (integer)
count1 dd ? ; cycle count
count2 dd ? ; cycle*10000H
work ends
cseg segment dword public use32 'CODE'
assume cs:cseg,ds:cseg
public sndVoiceChange
db 'sndVoiceGhange',14
sndVoiceChange proc near
push ebp
mov ebp,esp
push esi
push edi
push ebx
mov esi,[ebp].wadd ; esi <-- work area top add
mov ecx,[ebp].paradd ; ecx <-- para. add.
xor edx,edx ; edx=count
main01: mov eax,[ecx][edx*4] ; para. --> work area
mov [esi][edx*4],eax
inc edx
cmp edx,2
jb main01
mov ebx,[ebp].source ; ebx <-- source snd. add.
mov edi,[ebp].new ; edi <-- new snd. add.
xor edx,edx ; head trans
main02: mov eax,[ebx][edx*4]
mov [edi][edx*4],eax
inc edx
cmp edx,8
jb main02
mov ecx,[ebx+12] ; ecx <-- length
mov [esi].rend,ecx
cmp ecx,0
je mainE
add ebx,32 ; add head(32Byte)
add edi,32
add [esi].rend,ebx
sub [esi].rend,1
mov eax,[esi].cycle ; count set
cmp eax,0
jne main00
mov eax,1
mov [esi].cycle,eax
main00: mov [esi].count1,eax
xor edx,edx ; set data
mov [esi].point,edx
mov [esi].ratea,edx
mov eax,[esi].mode
shld edx,eax,16
shl eax,16
mov [esi].rate,eax
mov [esi].rate+4,edx
cmp edx,0
je main03
mov eax,[esi].mode ; hi
sub eax,10000H
mov [esi].rated,eax
mov eax,[esi].cycle ; set count2
shl eax,16
mov [esi].count2,eax
jmp main04
main03: mov eax,10000H
sub eax,[esi].mode
mov [esi].rated,eax
mov eax,10000H ; set count2
sub eax,[esi].rated
mul dword ptr [esi].cycle
mov [esi].count2,eax
main04: mov al,[ebx] ; trans while zero
mov [edi],al
inc ebx
inc edi
dec ecx
je mainE
and al,7fH
je main04
dec ebx
dec edi
inc ecx
mov [esi].point+4,ebx
xor eax,eax
add eax,dword ptr [esi].rate+4
je main05
call hi
jmp mainE
main05: call lw
mainE:
pop ebx
pop edi
pop esi
mov esp,ebp
pop ebp
ret
hi: lea eax,[esi].point
call smp ; ov.smp.
call wr ; write
dec ecx
je hiE
; mov ax,[edi-2] ; cross check
; cmp ax,8080H
; je hi00
; and eax,8080H
; cmp eax,80H
call close_ck
jne hi03
hi00: mov eax,[esi].rated ; ratea=ratea+rated
add [esi].ratea,eax
hi01: mov eax,[esi].ratea
cmp eax,[esi].count2
jb hi03
sub eax,[esi].count2 ; make wave
mov [esi].ratea,eax
mov eax,[esi].point ; point -> buf.
mov edx,[esi].point+4
mov [esi].pbuf,eax
mov [esi].pbuf+4,edx
mov eax,[esi].cycle ; set cycle count
mov [esi].count1,eax
hi02: call adp ; loop start
lea eax,[esi].point
call smp
call wr
dec ecx
je hiE
; mov ax,[edi-2]
; cmp ax,8080H
; je hi0A
; and eax,8080H
; cmp eax,80H
call close_ck
jne hi02 ; loop end
hi0A: dec dword ptr [esi].count1 ; cycle count
jne hi02
mov eax,[esi].pbuf ; buf. -> point
mov edx,[esi].pbuf+4
mov [esi].point,eax
mov [esi].point+4,edx
dec edi ; 1Byte over write
; 継ぎ接ぎを滑らかにする 1994 1
dec edi
call red_m_o
sar eax,2 ; 読んだデータを1/4に
call wr ; 半分にして書き直し( ここで inc edi してる)
lea eax,[esi].point
call smp
sar eax,2 ; 1/4に
call wr
jmp hi01
hi03: call adp
jmp hi
hiE: ret
lw: lea eax,[esi].point
call smp ; ov.smp.
call wr ; write
dec ecx
je lwE
; mov ax,[edi-2] ; cross check
; cmp ax,8080H
; je lw00
; and eax,8080H
; cmp eax,80H
call close_ck
jne lw03
lw00: mov eax,[esi].rated ; ratea=ratea+rated
add [esi].ratea,eax
lw01: mov eax,[esi].ratea
cmp eax,[esi].count2
jb lw03
sub eax,[esi].count2 ; delete wave
mov [esi].ratea,eax
mov [esi].pbuf,ecx ; count(ecx,edi) -> buf.
mov [esi].pbuf+4,edi
mov eax,[esi].cycle ; set cycle count
mov [esi].count1,eax
lw02: call adp ; loop start
lea eax,[esi].point
call smp
call wr
dec ecx
je lwE
; mov ax,[edi-2]
; cmp ax,8080H
; je lw0A
; and eax,8080H
; cmp eax,80H
call close_ck
jne lw02 ; loop end
lw0A: dec dword ptr [esi].count1 ; cycle count
jne lw02
mov ecx,[esi].pbuf ; buf. -> count(ecx,edi)
mov edi,[esi].pbuf+4
dec edi ; 1Byte over write
; 継ぎ接ぎを滑らかにする 1994 1
dec edi
call red_m_o
sar eax,2 ; 読んだデータを1/4に
call wr ; 半分にして書き直し( ここで inc edi してる)
lea eax,[esi].point
call smp
sar eax,2 ; 1/4に
call wr
jmp lw01
lw03: call adp
jmp lw
lwE: ret
; 出来上がったデータを読む
red_m_o: mov al,[edi-1] ; read
and eax,0ffH
cmp eax,128
jb red01
mov edx,eax
mov eax,128
sub eax,edx
red01: ret
; edi-4を境にクロスしてるかをフィルタ(平均化)にかけて判断
; eax = 0ならクロス, eax != 0ならノンクロス
close_ck:
push ecx
push edx
; mov eax,[edi-8]
mov edx,[esi].(point+4) ; オリジナルのデータを見るように変更
mov eax,[edx-2]
shld edx,eax,8
cmp dl,80h
jb cls00
mov dh,dl
mov dl,80h
sub dl,dh
cls00:
movsx edx,dl
mov ecx,edx
shld edx,eax,16
cmp dl,80h
jb cls01
mov dh,dl
mov dl,80h
sub dl,dh
cls01:
movsx edx,dl
; shl edx,2
add ecx,edx
shld edx,eax,24
cmp dl,80h
jb cls02
mov dh,dl
mov dl,80h
sub dl,dh
cls02:
movsx edx,dl
; shl edx,2
add ecx,edx
shld edx,eax,32
cmp dl,80h
jb cls03
mov dh,dl
mov dl,80h
sub dl,dh
cls03:
movsx edx,dl
add ecx,edx
cmp ecx,0
jg cls_no
; mov eax,[edi-4]
mov edx,[esi].(point+4) ; オリジナルのデータを見るように変更
mov eax,[edx-1]
shld edx,eax,8
cmp dl,80h
jb cls10
mov dh,dl
mov dl,80h
sub dl,dh
cls10:
movsx edx,dl
mov ecx,edx
shld edx,eax,16
cmp dl,80h
jb cls11
mov dh,dl
mov dl,80h
sub dl,dh
cls11:
movsx edx,dl
; shl edx,2
add ecx,edx
shld edx,eax,24
cmp dl,80h
jb cls12
mov dh,dl
mov dl,80h
sub dl,dh
cls12:
movsx edx,dl
; shl edx,2
add ecx,edx
shld edx,eax,32
cmp dl,80h
jb cls13
mov dh,dl
mov dl,80h
sub dl,dh
cls13:
movsx edx,dl
add ecx,edx
cmp ecx,0
jl cls_no
xor eax,eax
jmp cls_end
cls_no:
xor eax,eax
sub eax,1
cls_end:
pop edx
pop ecx
ret
; POINT=POINT+RATE
adp: push eax
push edx
mov eax,[esi].point
mov edx,[esi].point+4
add eax,[esi].rate
adc edx,[esi].rate+4
cmp edx,[esi].rend
jb adp01
xor eax,eax
mov edx,[esi].rend
adp01: mov [esi].point,eax
mov [esi].point+4,edx
pop edx
pop eax
ret
; WRITE DATA
; eax -> pcm data -> [edi] & inc edi
wr: cmp eax,0 ; write
js wr01
je wr01
cmp eax,128 ; +
jb wr02
mov eax,127
jmp wr02
wr01: mov edx,eax ; -
mov eax,128
sub eax,edx
cmp eax,256-1 ; data255はloopStopの意味があるから除外 1993 12
jb wr02
mov eax,255-1 ; data255はloopStopの意味があるから除外 1993 12
wr02: mov [edi],al
inc edi
ret
; OVER SAMPLING for PCM DATA(8bit)
;input eax = 64bit(32bit/decimal,32bit/integer) data address(ds:)
;output eax = over sampring data ( 32bit sign (-128 -- +127) )
smp: push ebx
push ecx
push edx
push esi
push edi
mov ebx,[eax] ; ebx = decimal
mov esi,[eax+4] ; esi = integer
shr ebx,24 ; ebx --> 8bit
jne smp00
mov al,[esi] ; decimal=0
and eax,0ffH
cmp eax,128
jb smp0A
mov edx,eax
mov eax,128
sub eax,edx
smp0A: jmp smp06
smp00:
mov eax,[esi-1] ; 周囲がみな無信号ならノイズを出さないよう直接0を返す
cmp eax,80808080h
jne smp0B
xor eax,eax
jmp smp06
smp0B:
call smp01
smp01: pop edi
add edi,smptb-smp01 ; edi = table point
mov al,[esi]
and eax,0ffH
cmp eax,128
jb smp02
mov edx,eax
mov eax,128
sub eax,edx
smp02: add eax,128
mul byte ptr cs:[edi][ebx]
mov ecx,eax
mov al,[esi-1]
and eax,0ffH
cmp eax,128
jb smp03
mov edx,eax
mov eax,128
sub eax,edx
smp03: add eax,128
mul byte ptr cs:[edi][ebx+256]
sub ecx,eax
mov eax,ebx ; ebx = 256 - ebx
mov ebx,256
sub ebx,eax
mov al,[esi+1]
and eax,0ffH
cmp eax,128
jb smp04
mov edx,eax
mov eax,128
sub eax,edx
smp04: add eax,128
mul byte ptr cs:[edi][ebx]
add ecx,eax
mov al,[esi+2]
and eax,0ffH
cmp eax,128
jb smp05
mov edx,eax
mov eax,128
sub eax,edx
smp05: add eax,128
mul byte ptr cs:[edi][ebx+256]
sub ecx,eax
sub ecx,128*256
sar ecx,8
mov eax,ecx
smp06: pop edi
pop esi
pop edx
pop ecx
pop ebx
ret
smptb db 255,255,255,254,254,253,253,252
db 252,251,251,250,249,249,248,248
db 247,246,246,245,244,244,243,243
db 242,241,240,240,239,238,238,237
db 236,236,235,234,233,233,232,231
db 230,229,229,228,227,226,225,225
db 224,223,222,221,221,220,219,218
db 217,216,215,214,214,213,212,211
db 210,209,208,207,206,205,204,204
db 203,202,201,200,199,198,197,196
db 195,194,193,192,191,190,189,188
db 187,186,185,184,183,182,181,180
db 179,178,177,176,175,174,172,171
db 170,169,168,167,166,165,164,163
db 162,161,160,158,157,156,155,154
db 153,152,151,150,148,147,146,145
db 144,143,142,141,139,138,137,136
db 135,134,133,132,130,129,128,127
db 126,125,123,122,121,120,119,118
db 117,115,114,113,112,111,110,108
db 107,106,105,104,103,101,100,099
db 098,097,096,094,093,092,091,090
db 089,087,086,085,084,083,082,080
db 079,078,077,076,075,073,072,071
db 070,069,068,067,065,064,063,062
db 061,060,058,057,056,055,054,053
db 052,051,049,048,047,046,045,044
db 043,042,040,039,038,037,036,035
db 034,033,032,030,029,028,027,026
db 025,024,023,022,021,020,019,018
db 016,015,014,013,012,011,010,009
db 008,007,006,005,004,003,002,001
db 000,000,001,001,001,002,002,002
db 003,003,003,003,004,004,004,005
db 005,005,005,006,006,006,006,007
db 007,007,007,008,008,008,008,009
db 009,009,009,009,010,010,010,010
db 010,011,011,011,011,011,011,012
db 012,012,012,012,012,013,013,013
db 013,013,013,013,014,014,014,014
db 014,014,014,014,014,015,015,015
db 015,015,015,015,015,015,015,015
db 015,016,016,016,016,016,016,016
db 016,016,016,016,016,016,016,016
db 016,016,016,016,016,016,016,016
db 016,016,016,016,016,016,016,016
db 016,016,016,016,016,016,016,016
db 016,016,016,016,016,016,016,016
db 016,016,016,016,016,016,016,016
db 016,016,015,015,015,015,015,015
db 015,015,015,015,015,015,015,015
db 014,014,014,014,014,014,014,014
db 014,014,014,013,013,013,013,013
db 013,013,013,013,012,012,012,012
db 012,012,012,012,012,011,011,011
db 011,011,011,011,011,010,010,010
db 010,010,010,010,009,009,009,009
db 009,009,009,008,008,008,008,008
db 008,008,007,007,007,007,007,007
db 007,006,006,006,006,006,006,005
db 005,005,005,005,005,004,004,004
db 004,004,004,003,003,003,003,003
db 003,002,002,002,002,002,002,001
db 001,001,001,001,001,000,000,000
sndVoiceChange endp
cseg ends
end